package luj.game.robot.internal.instance.boss.command.execute;

import luj.bean.api.BeanContext;
import luj.bean.api.bean.Bean;
import luj.cluster.api.actor.Tellable;
import luj.game.robot.api.action.CommandService;
import luj.game.robot.internal.concurrent.instance.command.service.factory.ParamBeanMaker;
import luj.game.robot.internal.concurrent.parent.command.BossExecCommandMsg;

import java.util.Map;
import java.util.function.BiFunction;

public class BossExecuteStarter {

  public BossExecuteStarter(Tellable bossRef, Class<?> targetCmd, Class<?> paramType, BiFunction<CommandService.Param, ?, CommandService.Param> paramBuilder, BeanContext lujbean) {
    _bossRef = bossRef;
    _targetCmd = targetCmd;
    _paramType = paramType;
    _paramBuilder = paramBuilder;
    _lujbean = lujbean;
  }

  public void start() {
    String targetCmd = _targetCmd.getName();
    Map<String, Object> param = resolveParam();

    var msg = new BossExecCommandMsg(targetCmd, param);
    _bossRef.tell(msg);
  }

  @SuppressWarnings("unchecked")
  private Map<String, Object> resolveParam() {
    var builder = (BiFunction<CommandService.Param, Object, CommandService.Param>) _paramBuilder;
    Bean<?> paramBean = new ParamBeanMaker(_paramType, builder::apply, _lujbean).make();
    return paramBean.getFieldMap();
  }

  private final Tellable _bossRef;
  private final Class<?> _targetCmd;

  private final Class<?> _paramType;
  private final BiFunction<CommandService.Param, ?, CommandService.Param> _paramBuilder;
  private final BeanContext _lujbean;
}
